L'atelier A2plus est un atelier externe de Freecad qui permet l'assemblage de plusieurs pièces.
Cette documentation d'A2plus porte sur la version 0.4.56 ou plus récente.
L’atelier A2plus est un complément à FreeCAD. Il peut être facilement installé via le menu Gestionnaire des extensions à partir de Outils → Gestionnaire des extensions.
A2plus est en cours de développement et bénéficiera fréquemment de nouvelles fonctionnalités. Par conséquent, vous devez le mettre à jour régulièrement en utilisant également le menu Outils→ Gestionnaire des extensions.
Le code A2plus est hébergé et développé sur GitHub et peut également être installé manuellement en le copiant dans le répertoire Mod de FreeCAD.
Commencez par passer à la barre d’outils A2plus dans FreeCAD. Pour créer un assemblage, créez un nouveau fichier dans FreeCAD. Au début, ce fichier doit être enregistré. Il est recommandé (mais pas nécessaire) de l’enregistrer dans le même dossier que les pièces à assembler.
Vous pouvez maintenant ajouter des pièces à l'assemblage à l'aide du bouton de la barre d'outils ou
. Le bouton
ajoute tous les corps du fichier sélectionné en une seule pièce. Lorsque vous utilisez le bouton
vous pouvez choisir quelle partie d'un fichier doit être importée en tant que partie. De cette façon, on peut par exemple uniquement importer une esquisse pour assembler d'autres pièces en utilisant l'esquisse pour déterminer les positions des pièces.
La première pièce ajoutée obtient une position fixe par défaut. (Vous pouvez la modifier ultérieurement via la propriété Donnéesfixed Position.)
Les pièces déjà présentes dans l'assemblage peuvent être clonées avec le bouton de la barre d'outils .
Pour modifier une pièce de l'assemblage, sélectionnez-la dans l'arbre du modèle et utilisez le bouton de la barre d'outils . Cela ouvrira la pièce dans un nouvel onglet dans FreeCAD ou basculera vers son onglet si le fichier est déjà ouvert.
Pour mettre à jour les pièces modifiées dans les assemblages, cliquez sur le bouton de la barre d'outils . Le bouton de la barre d'outils
importe également les pièces mais de manière récursive sur les Sous-assemblages possibles. Si vous sélectionnez une ou plusieurs pièces dans l'arborescence de FreeCAD, A2plus vous demandera de ne mettre à jour que les pièces sélectionnées.
Les pièces importées conservent leurs dépendances externes et peuvent être modifiées. Pour des pièces bien définies telles que des vis, il est toutefois utile que leur forme ne puisse pas être modifiée. Ceci peut être réalisé avec le bouton de la barre d’outils qui convertit la pièce sélectionnée en une copie statique de la pièce d'origine.
Pour enregistrer l’ensemble et le refermer par la suite, vous pouvez utiliser le bouton de la barre d’outils .
Le basculement du bouton de la barre d'outils définit la manière dont vous pouvez sélectionner plusieurs arêtes, faces, etc. : soit par un simple clic, soit par Ctrl+clic.
L'assemblage des pièces se fait en ajoutant des contraintes entre les pièces. Après une contrainte, A2plus déplacera les pièces en fonction de la contrainte, si possible.
Pour créer une contrainte entre les pièces, maintenez la touche Ctrl enfoncée et sélectionnez soit une arête soit une face de deux pièces. Cliquez ensuite sur le bouton de la barre d'outils de la contrainte souhaitée. Une boîte de dialogue apparaîtra, décrite dans la section Contraintes. La contrainte sera ajoutée dans l'arborescence du modèle attachée aux pièces affectées.
Pour les contraintes complexes entre les pièces, A2plus peut ne pas résoudre les contraintes. Par conséquent, consultez également la section Dépannage pour connaître les stratégies permettant de résoudre de tels cas.
Plus vous ajoutez de pièces, plus il est important de conserver une trace. A2plus propose donc ces outils pour déplacer et visualiser des pièces :
Lors de la création d'une contrainte, une boîte de dialogue s'affiche après avoir appuyé sur un bouton de la barre d'outils de contrainte:
Ci-dessus : la boîte de dialogue Propriétés de la contrainte A2plus
Pour certaines contraintes, il vous permet de modifier la direction des contraintes. Avec le bouton Solve vous pouvez vérifier au préalable si cette nouvelle contrainte peut être résolue par A2plus. Sinon, consultez la section Dépannage.
Les contraintes peuvent être désactivées en modifiant sa visibilité. Pour ce faire, sélectionnez la contrainte dans l'arborescence et appuyez sur Espace. Cela bascule la propriété DonnéesSuppressed. Une contrainte supprimée n'est pas prise en compte lorsque l'assemblage est résolu.
A2plus fournit les contraintes suivantes :
Sélectionnez un sommet (point) sur chaque pièce. Le bouton de la barre d'outils ajoute la contrainte pointIdentity. Cela fera coïncider les sommets.
Sélectionnez un vertex (point) ou un edge (ici arc) de cercle (sélectionnera son centre) ou une face sphérique (sélectionnera également son centre) d'une part et un edge d'autre part. Le bouton de la barre d'outils ajoute la contrainte pointOnLine. Cela mettra le vertex sur l'edge.
Sélectionnez un vertex (point) ou un edge (ici arc) de cercle (sélectionnera son centre) ou la face d'une sphère (sélectionnera également son centre) d'une par et un plan d'autre part. Le bouton de la barre d’outils ajoute la contrainte pointOnPlane. Le dialogue de contrainte vous permet de spécifier un décalage entre le point et le plan. Ce décalage peut également être inversé entre les deux côtés du plan. Si le décalage est nul, la contrainte placera le sommet sur le plan.
Sélectionnez une face sphérique ou un vertex (point) sur les deux pièces. Le bouton de la barre d'outils ajoute la contrainte sphereCenterIdent. Cela fera coïncider les centres des sphères, le centre de la sphère et le sommet, ou les sommets.
Sélectionnez un bord circulaire sur les deux pièces. Le bouton de la barre d'outils ajoute la contrainte circularEdge. Le dialogue de contrainte vous permet de spécifier un décalage entre les arêtes. Ce décalage peut également être inversé. Vous pouvez en outre définir le sens de la contrainte et verrouiller la rotation des pièces. Si le décalage est nul, la contrainte placera les arêtes concentriques dans le même plan.
Sélectionnez une face cylindrique ou un bord linéaire sur les deux pièces. Le bouton de la barre d'outils ajoute la contrainte axisCoincident. Le dialogue de contrainte vous permet de spécifier la direction de l'axe.La boîte de dialogue vous permet en outre de verrouiller la rotation des pièces. La contrainte fera coïncider les axes ou les lignes.
Sélectionnez une face cylindrique ou un bord linéaire sur les deux pièces. Le bouton de la barre d'outils ajoute la contrainte axisParallel. Le dialogue de contrainte vous permet de spécifier la direction de l'axe. La contrainte rendra les axes ou les lignes parallèles.
Sélectionnez une face cylindrique ou un bord linéaire sur une pièce et un plan sur l'autre pièce. Le bouton de la barre d'outils ajoute la contrainte axisPlaneParallel. La contrainte rendra l'axe ou la ligne parallèle au plan.
Sélectionnez une face cylindrique ou un bord linéaire sur une partie et un plan sur l'autre partie. Le bouton de la barre d’outils ajoute la contrainte axisPlaneNormal. La contrainte rendra l'axe ou la ligne normale au plan.
Sélectionnez une face cylindrique ou une arête linéaire sur une partie et un plan sur l'autre partie. Le bouton de la barre d'outils ajoute la contrainte axisPlaneAngle. La contrainte rendra d'abord l'axe parallèle au plan. Ensuite, vous pouvez ajuster l'angle de l'axe dans la boîte de dialogue des paramètres de contrainte qui apparaît.
Sélectionnez un plan sur les deux pièces. Le bouton de la barre d'outils ajoute la contrainte planesParallel. La boîte de dialogue de contrainte vous permet de spécifier le sens de la contrainte. La contrainte rendra les plans parallèles.
Sélectionnez un plan sur les deux pièces. Le bouton de la barre d'outils ajoute la contrainte planeCoincident. La boîte de dialogue de contrainte vous permet de spécifier une direction de contrainte et un décalage entre les plans. Ce décalage peut également être inversé. Si le décalage est nul, la contrainte fera coïncider les plans.
Sélectionnez un plan sur les deux pièces. Le bouton de la barre d'outils ajoute la contrainte angledPlanes. Le dialogue de contrainte vous permet de spécifier un angle entre les plans. La contrainte va d'abord rendre les plans parallèles et définir l'angle spécifié.
Sélectionnez un bord fermé ou un plan sur les deux pièces. Le bouton de la barre d'outils ajoute la contrainte centerOfMass. Le dialogue de contrainte vous permet de spécifier un décalage entre les arêtes ou les plans. Ce décalage peut également être inversé. Vous pouvez en outre définir le sens de la contrainte et verrouiller la rotation des pièces. Si le décalage est nul, la contrainte placera les arêtes ou les plans dans le même plan.
Un assemblage peut contenir d'autres assemblages. Ils sont ajoutés comme des pièces en appuyant sur le bouton de la barre d’outils et en sélectionnant un fichier *.FCStd contenant un assemblage. De tels sous-ensembles peuvent également être édités comme des pièces à l’aide du bouton de la barre d’outils
. Assurez-vous, pour les étapes d'assemblage supérieures, que vous mettez à jour l'assemblage via le bouton de la barre d'outils
quand il y a eu des changements.
Les contraintes possibles pour une sélection sont affichées dans la barre d’outils et dans la fenêtre de dialogue "Outils de contrainte" en activant les boutons correspondants. La fenêtre de dialogue "Outils de contrainte" s’ouvre via le bouton de la barre d’outils . Il est prévu de rester ouvert pour pouvoir ajouter rapidement plusieurs contraintes à l’assemblage.
Les contraintes existantes peuvent être modifiées en les sélectionnant dans l'arborescence du modèle, puis en double-cliquant dessus ou en utilisant le bouton de la barre d'outils . Cela ouvre la boîte de dialogue "Propriétés de contrainte".
Les contraintes peuvent être temporairement supprimées en les sélectionnant dans l'arbre du modèle et en modifiant la propriété de l'élément d'arbreDonnéesSuppressed.
Les contraintes peuvent être supprimées en les sélectionnant dans l'arborescence du modèle et en appuyant sur Suppr ou en sélectionnant une pièce avec des contraintes dans l'arborescence du modèle et en utilisant le bouton de la barre d'outils .
Toutes les contraintes peuvent être résolues à tout moment avec le bouton de la barre d’outils . Si le bouton de la barre d'outils
est activé, une résolution est automatiquement effectuée après chaque édition d'une contrainte.
Le bouton de la barre d'outils affecte la contrainte qui a été ajoutée le plus récemment. Il inverse la direction de la contrainte.
Avec l'outil , il est possible d'afficher et d'inspecter les contraintes existantes. Après avoir cliqué sur l'outil, une boîte de dialogue s'ouvre. Vous pouvez alors soit sélectionner une pièce dans l'arborescence et cliquer sur le bouton Import from part pour obtenir toutes les contraintes de cette pièce, soit sélectionner une ou plusieurs contraintes dans l'arborescence et cliquer sur le bouton Import from Tree. Le résultat est que vous obtenez toutes les informations sur les contraintes. En cliquant dans la colonne Suppress, une seule contrainte peut être supprimée. Pour plus de fonctionnalités, suivez les infobulles des autres boutons de la boîte de dialogue.
Pour créer des listes de pièces d'assemblages, les différentes pièces de l'assemblage doivent obtenir des informations sur les pièces pouvant être lues par A2plus. Ceci est fait en éditant la pièce en utilisant le bouton de la barre d’outils . Dans la partie ouverte, appuyez sur le bouton de la barre d’outils
et une feuille de calcul portant le nom #PARTINFO# est créée.
La structure de la feuille de calcul est la suivante :
Remplissez les champs gris avec les informations que vous avez et que vous souhaitez inclure dans la liste de pièces finale.
Dans l'assemblage ou le sous-assemblage, utilisez le bouton de la barre d'outils . Il vous demandera si vous souhaitez effectuer une itération récursive sur tous les sous-assemblages. Cliquez sur "Oui". Cela crée une nouvelle feuille de calcul avec le nom #PARTSLIST#. Il contient les informations des différentes feuilles de calcul #PARTSINFO# des pièces dans une liste comme celle-ci :
La position (POS) est automatiquement définie en fonction de l'apparence des pièces dans l'arbre du modèle. La pièce de niveau supérieur recevra POS 1.
La quantité (QTY) est automatiquement calculée à partir de l'assemblage. Si une pièce est deux fois dans l'assemblage, elle aura QTY 2.
Si vous avez mis à jour une information de pièce, vous pouvez actualiser la liste de pièces en appuyant sur le bouton de la barre d’outils à nouveau.
Pour les sous-ensembles, vous pouvez également créer une feuille de calcul d’informations à l’aide du bouton de la barre d’outils . Lorsque vous créez ou mettez à jour la liste de pièces de l'assemblage principal, cette information est utilisée si vous cliquez sur "Non" pour la question si vous souhaitez effectuer une itération récursive sur tous les sous-assemblages. Ensuite, les différentes pièces ne figurent pas dans la liste de pièces, mais uniquement les sous-assemblages.
Le bouton de la barre d'outils crée un fichier HTML avec la structure de votre assemblage. Le fichier sera créé par défaut dans le dossier de votre fichier d'assemblage. La structure ressemble à celle-ci:
Le bouton permet d’étiqueter chaque partie de l’assemblage avec ses degrés de liberté. De plus, il affiche une liste avec toutes les pièces et leurs dépendances. La liste est sortie dans le widget Vue rapport de FreeCAD. Si ce widget n'est actuellement pas visible, vous pouvez l'afficher soit en cliquant avec le bouton droit de la souris sur une partie vide de la zone de la barre d'outils FreeCAD, puis en le choisissant dans le menu contextuel qui apparaît, ou avec le menu Affichage → Panneaux → Vue rapport.
Les libellés des degrés de liberté peuvent être supprimées en cliquant à nouveau sur le bouton .
Le bouton identifie chaque partie de l'assemblage dans la vue 3D par son nom. Les étiquettes des pièces peuvent être supprimées en cliquant sur le bouton
.
Parfois, il est nécessaire de combiner l’ensemble du montage en une seule forme. Cette forme peut ensuite être utilisée par exemple pour l’impression 3D dans l’atelier Mesh ou pour les dessins dans l’atelier TechDraw. Il est créé en utilisant le bouton de la barre d’outils . La forme est par défaut non visible.Utilisez le même bouton de la barre d’outils pour mettre à jour la forme en cas de modification de l’assemblage.
Avec le menu A2plus → Misc → Convert absolute paths of imported parts to relative ones vous pouvez convertir les chemins absolus des pièces importées en pièces relatives.
Les préférences de a2plus sont accessibles via le menu Édition → Préférences de FreeCAD et dans la section "A2plus". Vous pouvez définir les options suivantes :
Problèmes connus :
Tôt ou tard, vous aurez le problème qu'A2plus ne peut pas résoudre les contraintes que vous avez définies.Pour surmonter cela, il existe différentes stratégies :
Il s'agit de la méthode la plus sûre lorsque vous avez plusieurs contraintes : cet outil tente de résoudre une contrainte après l'autre jusqu'à ce qu'il trouve la contrainte en conflit. Ensuite, vous pouvez continuer avec les autres stratégies pour résoudre la contrainte identifiée. L'outil est appelé à l'aide du bouton de la barre d'outils .
Parfois, les contraintes semblent être systématiquement définies mais elles ne peuvent néanmoins pas être résolues. Un exemple : supposons que vous ayez un ensemble de contraintes plans Parallèles pour deux plans. Vous souhaitez maintenant définir pour les mêmes plans la contrainte plans coïncidents et A2plus ne peut pas résoudre ce problème. Alors les directions de contrainte des planesParallel et planeCoincident sont différentes. Utilisez la même direction pour les deux contraintes afin de résoudre ce problème.
A2plus propose de vérifier automatiquement la bonne direction pour toutes les contraintes de l'assemblage à l'aide du bouton de la barre d'outils .
La plupart des cas de contraintes insolubles se produisent directement lors de l'ajout d'une nouvelle contrainte. La solution consiste alors à supprimer la dernière contrainte que vous avez ajoutée. A2plus le proposera également.
Parfois, la stratégie de suppression est la seule, par exemple lorsque vous modifiez une pièce dans FreeCAD afin que des faces ou des arêtes liées à des contraintes soient manquantes. Vous devez ensuite supprimer une contrainte liée à la pièce modifiée à la fois. Utilisez le bouton de la barre d'outils après chaque suppression pour voir si vous avez atteint un état que le solveur peut résoudre.
Lorsque vous avez un assemblage qui peut être résolu, ajoutez étape par étape les contraintes dont vous avez besoin.
Dans de nombreux cas, le solveur ne nécessite que des meilleures valeurs de départ pour résoudre les contraintes. Prenons par exemple le cas où vous avez une pièce essieu et une pièce roue. Vous ajoutez une contrainte axisCoincident et n'obtenez aucune information sur l'échec du solveur, mais les pièces ne sont pas déplacées en conséquence et dans le l'onglet Afficher rapport de FreeCAD, vous voyez "REACHED POS-ACCURACY :0.0". Une solution à cela consiste à rapprocher les pièces de la position souhaitée par la contrainte.
Remarque : Assurez-vous qu'au moins une pièce de la contrainte a la propriété DonnéesPosition fixe définie sur false.
Si vous avez oublié certaines fonctionnalités de votre pièce après l'importation dans un assemblage A2plus, vérifiez la propriété DonnéesTip.
A2plus importe des corps de pièces avec toutes leurs fonctions jusqu'à la fonction Tip. Cela est judicieux car le fait de définir Tip sur une certaine fonction signifie que toutes les fonctions derrière Tip ne doivent pas apparaître dans la partie finale. Donc, si vous manquez une fonction de pièce dans A2plus, ouvrez la pièce via le bouton de la barre d'outils puis sélectionnez un corps et regardez sa propriété DonnéesTip. Si Tip ne se trouve pas à la fonction où vous le souhaitez, cliquez avec le bouton droit sur la fonction où Tip devrait être et choisissez
Set tip. Enfin, enregistrez la pièce et rechargez l'assemblage à l'aide du bouton de la barre d'outils
.
Si vous ne voyez pas clairement pourquoi certaines contraintes ne peuvent pas être résolues, vous pouvez utiliser le bouton de la barre d’outils . Ceci résoudra toutes les contraintes et les regroupera à nouveau sous les différentes pièces.
Les assemblages créés avec A2plus antérieurs à mars 2019 n'affichent pas les icônes correctes pour les pièces importées et ont des propriétés obsolètes. Ces assemblages peuvent être migrés vers A2plus version 0.4.35 et plus récente à l'aide du menu Migrer les proxys de pièces importées. Après cela, vous devez enregistrer et rouvrir votre fichier d'assemblage.
Cette stratégie n'est pas nécessaire pour Windows.
Sur certains systèmes d'exploitation, vous pouvez rencontrer des problèmes si les noms de fichier ou les chemins de fichier des pièces ou de l'assemblage contiennent des caractères accentués. Par conséquent, évitez ces caractères et les caractères spéciaux en général.
Cette stratégie n'est plus nécessaire pour les assemblages créés avec A2plus 0.3.11 ou une version plus récente, car A2plus émet désormais un avertissement pour les positions fixes manquantes.
Lorsque vous définissez une contrainte entre deux pièces et qu'aucune pièce n'a la propriété DonnéesPosition fixe définie sur true ou est liée par une contrainte à une pièce avec DonnéesPosition fixe définie sur true, la contrainte ne peut pas être résolue. La même chose se produit si les deux pièces de la contrainte ont DonnéesPosition fixe défini sur true.
Ensuite, A2plus transmet les informations relatives à la solution défaillante, mais parfois, vous voyez que les pièces ne sont pas déplacées en conséquence et dans l'onglet Afficher rapport de FreeCAD, vous voyez "REACHED POS-ACCURACY :0.0". Cela signifie que le solveur a fini sans erreurs mais qu'il n'a pas pu résoudre les contraintes.
Par conséquent, vérifiez qu'au moins une de vos pièces de l'ensemble a DonnéesPosition fixe définie sur true. Assurez-vous ensuite que vous ne définissez des contraintes que sur une pièce qui est en quelque sorte connectée à la pièce fixe. Pour visualiser ces dépendances, reportez-vous à la section Structure de l'assemblage.
Cette stratégie n'est plus nécessaire pour les assemblages créés avec A2plus 0.4.0 ou plus récent, car A2plus fait pivoter automatiquement les pièces en arrière-plan afin d'obtenir un angle de départ suffisant pour le solveur.
Le solveur échoue souvent pour la contrainte angledPlanes si les deux plans sélectionnés ont actuellement un angle de 0 ° ou 180 °. (Les pièces ne sont pas déplacées en conséquence et dans l'onglet "Vue Rapport" de FreeCAD, vous voyez "REACHED POS-ACCURACY :0.0".) Une solution consiste à faire pivoter une pièce de quelques degrés à l'aide de la fonction de transformation de FreeCAD (cliquez avec le bouton droit de la souris sur la pièce dans l’arbre du modèle et sélectionnez dans le menu contextuel Transformer).
Remarque : Assurez-vous qu'au moins une pièce de la contrainte a la propriété DonnéesPosition fixe définie sur false.
A2plus propose des animations par glisser-déposer et via des scripts Python.
Les animations de glissement sont interactives. Vous les déclenchez en faisant glisser une partie de l'assemblage. Pour obtenir ce genre d'animations :
Voici un exemple d'assemblage pour tester l'animation de glissement : A2p_example-for-dragging-animation.FCStd
Ci-dessus : l'animation de glissement à l'aide de l'exemple d'assemblage
Bien que le mode glisser offre de belles animations interactives, elles ne sont parfois pas assez précises pour les screencasts ou les vidéos. Les animations scriptées ont l'avantage d'animer des mouvements et des rotations d'une manière définie. Vous pouvez par exemple faire pivoter une pièce exactement de 10° d'avant en arrière. Les exemples suivants utilisent un assemblage dans lequel une pièce doit être tournée. Si vous essayez d'animer cela en utilisant le mode glisser, vous verrez à quel point il est difficile d'obtenir une rotation d'avant en arrière que vous pouvez par exemple montrez votre patron dans une présentation. Avec l'exemple de script interactif, c'est une tâche facile.
Une animation scriptée fonctionne généralement de cette façon :
Il est également possible de modifier au lieu d'un paramètre de placement une contrainte, par exemple la distance entre 2 plans.
La façon la plus simple de scénariser une animation est une animation non interactive qui suit un mouvement défini. Voici un exemple : Téléchargez d'abord ce fichier d'assemblage : A2p_animated-example.FCStd et aussi ce script Python : A2p_animation-exemple-script.py.
Contenu du script. Les lignes commençant par un '#' décrivent ce que font les différentes lignes de script:
# import libraries
import time, math, PySide
import A2plus.a2p_solversystem as a2p_solver
# nous utilisons des pas de 1 degré
step = 1
# attendez 1 ms entre chaque étape
timeout = 0.001
# l'angle initial est de 0 degré
angle = 0
# nous prenons le document actuellement ouvert
document = FreeCAD.activeDocument()
# on veut changer plus tard l'angle de rotation de la pièce "star_wheel_001"
starWheel = document.getObject("star_wheel_001")
# définir une boîte de dialogue de progression allant de 0 à 360
progressDialog = PySide.QtGui.QProgressDialog(u"Animation progress", u"Stop", 0, 360)
# le bloc while est la boucle principale pour changer l'angle et résoudre
# les contraintes d'assemblage par la suite
while angle < 360: # exécute cette boucle jusqu'à ce que nous ayons fait un tour complet (360 degrés)
# augmenter l'angle de rotation
angle += step
# définit le nouvel angle dans la boîte de dialogue de progression
progressDialog.setValue(angle)
# change l'angle de rotation de la pièce "star_wheel_001"
starWheel.Placement.Rotation.Angle = math.radians(angle)
# résoud les contraintes
a2p_solver.solveConstraints(document, useTransaction=True)
# mettre à jour la vue après la résolution ('Gui' signifie 'interface utilisateur graphique')
FreeCADGui.updateGui()
# met en avant la boîte de dialogue de progression
PySide.QtGui.QWidget.raise_(progressDialog)
# si 'Stop' a été pressé dans la boîte de dialogue, quitte la boucle
if progressDialog.wasCanceled():
angle = 360
# attend un peu avant d'effectuer l'étape suivante
time.sleep(timeout)
Pour utiliser le script pour effectuer l'animation, nous devons :
Pour vous entraîner, changez simplement quelque chose dans le script et exécutez-le ensuite. Par exemple, augmentez «step» à «5».
Voici le résultat de l'exemple d'animation :
Le premier exemple de script a montré comment créer une animation sans rétroaction de l'utilisateur. Pour la plupart des applications, vous devez interagir avec l'animation. Par exemple, le problème intéressant dans l'exemple est de voir comment les broches d'entraînement traversent la rainure centrale de la roue. Pour regarder de plus près, vous pouvez présenter ce détail à vos collègues. Vous avez donc besoin d'une solution interactive.
Cela peut être fait en utilisant une boîte de dialogue d'animation personnalisée avec un curseur. En déplaçant le curseur, vous pouvez définir l'angle de rotation et donc faire pivoter d'avant en arrière à une position intéressante.
Nous utilisons le même fichier d'assemblage :A2p_animated-example.FCStd et ce script Python: A2p_animation-example-script.py.
Voici le contenu du script pour obtenir la boîte de dialogue d'animation interactive :
# import libraries
import time, math, PySide, sys
import FreeCAD.A2plus.a2p_solversystem as a2p_solver
from FreeCAD import Units
from PySide import QtCore, QtGui
# attendre 1 ms après chaque calcul
timeout = 0.001
# nous prenons le document actuellement ouvert
document = FreeCAD.activeDocument()
# on veut changer plus tard l'angle de rotation de la pièce "star_wheel_001"
starWheel = document.getObject("star_wheel_001")
class AnimationDlg(QtGui.QWidget): # the animation dialog
def __init__(self): # to initialize the dialog
super(AnimationDlg, self).__init__()
self.initUI()
def initUI(self): # définition des composants de dialogue
self.setMinimumSize(self.minimumSizeHint()) # définir la taille minimale de la boîte de dialogue au minimum
self.setWindowTitle('Animation Dialog')
# utiliser une disposition de grille pour l'ensemble du formulaire
self.mainLayout = QtGui.QGridLayout()
self.lineNo = 0 # first dialog grid line
# ajouter une étiquette de description
DescriptionLabel = QtGui.QLabel(self)
DescriptionLabel.setText("Change slider to change rotation angle")
self.mainLayout.addWidget(DescriptionLabel,self.lineNo,0,1,4)
# ligne de grille de dialogue suivante
self.lineNo += 1
# ajouter une étiquette; il n'y a pas besoin du «moi». préfixe parce que nous ne voulons pas changer l'étiquette plus tard
LabelMin = QtGui.QLabel(self)
LabelMin.setText("Min")
LabelMin.setFixedHeight(32)
self.mainLayout.addWidget(LabelMin,self.lineNo,0)
# ajouter une modification du spin pour définir le minimum du curseur
self.MinEdit = QtGui.QSpinBox(self)
# obtenir l'unité d'angle sous forme de chaîne
self.MinEdit.setSuffix(" " + str(FreeCAD.Units.Quantity(1, FreeCAD.Units.Angle))[2:])
self.MinEdit.setMaximum(999)
self.MinEdit.setMinimum(0)
self.MinEdit.setSingleStep(10)
self.MinEdit.setValue(0)
self.MinEdit.setFixedHeight(32)
self.MinEdit.setToolTip("Minimal angle for the slider")
QtCore.QObject.connect(self.MinEdit, QtCore.SIGNAL("valueChanged(int)"), self.setMinEdit)
self.mainLayout.addWidget(self.MinEdit,self.lineNo,1)
# ajoutez le curseur
self.slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
self.slider.setRange(0, 360)
self.slider.setValue(0)
self.slider.setFixedHeight(32)
self.slider.setToolTip("Move the slider to change the rotation angle")
QtCore.QObject.connect(self.slider, QtCore.SIGNAL("sliderMoved(int)"), self.handleSliderValue)
self.mainLayout.addWidget(self.slider,self.lineNo,2)
# ajouter une étiquette
LabelMax = QtGui.QLabel(self)
LabelMax.setText("Max")
LabelMax.setFixedHeight(32)
self.mainLayout.addWidget(LabelMax,self.lineNo,3)
# ajouter une modification de spin pour définir le maximum du curseur
self.MaxEdit = QtGui.QSpinBox(self)
# obtenir l'unité d'angle sous forme de chaîne
self.MaxEdit.setSuffix(" " + str(FreeCAD.Units.Quantity(1, FreeCAD.Units.Angle))[2:])
self.MaxEdit.setMaximum(999)
self.MaxEdit.setMinimum(1)
self.MaxEdit.setSingleStep(10)
self.MaxEdit.setValue(360)
self.MaxEdit.setFixedHeight(32)
self.MaxEdit.setToolTip("Maximal angle for the slider")
QtCore.QObject.connect(self.MaxEdit, QtCore.SIGNAL("valueChanged(int)"), self.setMaxEdit)
self.mainLayout.addWidget(self.MaxEdit,self.lineNo,4)
# ligne de grille de dialogue suivante
self.lineNo += 1
# ajouter un espaceur
self.mainLayout.addItem(QtGui.QSpacerItem(10,10), 0, 0)
# ajouter une étiquette
LabelCurrent = QtGui.QLabel(self)
LabelCurrent.setText("Current angle:")
LabelCurrent.setFixedHeight(32)
self.mainLayout.addWidget(LabelCurrent,self.lineNo,1)
# afficher l'angle actuel
self.CurrentAngle = QtGui.QLineEdit(self)
self.CurrentAngle.setText(str(0))
self.CurrentAngle.setFixedHeight(32)
self.CurrentAngle.setToolTip("Current rotation angle")
self.CurrentAngle.isReadOnly()
self.mainLayout.addWidget(self.CurrentAngle,self.lineNo,2)
# ajouter une étiquette pour l'unité
LabelUnit = QtGui.QLabel(self)
LabelUnit.setText("deg")
LabelUnit.setFixedHeight(32)
self.mainLayout.addWidget(LabelUnit,self.lineNo,3)
# bouton pour fermer la boîte de dialogue
self.Close = QtGui.QPushButton(self)
self.Close.setText("Close")
self.Close.setFixedHeight(32)
self.Close.setToolTip("Closes the dialog")
QtCore.QObject.connect(self.Close, QtCore.SIGNAL("clicked()"), self.CloseClicked)
self.mainLayout.addWidget(self.Close,self.lineNo,4)
# place la disposition de grille définie dans la boîte de dialogue
self.setLayout(self.mainLayout)
self.update()
def handleSliderValue(self):
# définir la valeur du curseur comme angle
starWheel.Placement.Rotation.Angle = math.radians(self.slider.value())
# angle de courant de sortie
self.CurrentAngle.setText(str(self.slider.value()))
# résoudre les contraintes
a2p_solver.solveConstraints(document)
# mettre à jour la vue après la résolution ('Gui' signifie 'interface utilisateur graphique')
FreeCADGui.updateGui()
# attendre un certain temps, important de donner du temps pour effectuer des calculs
time.sleep(timeout)
def setMinEdit(self):
# assurez-vous que le minimum est plus petit que le maximum
if self.MinEdit.value() >= self.MaxEdit.value():
self.MaxEdit.setValue(self.MinEdit.value() + 1)
self.slider.setRange(self.MinEdit.value(), self.MaxEdit.value())
def setMaxEdit(self):
# assurer que le minimum est plus petit que le maximum
if self.MinEdit.value() >= self.MaxEdit.value():
self.MinEdit.setValue(self.MaxEdit.value() - 1)
self.slider.setRange(self.MinEdit.value(), self.MaxEdit.value())
def CloseClicked(self):
AnimationDialog.close()
# créer et afficher la fenêtre de dialogue définie
AnimationDialog = AnimationDlg()
AnimationDialog.show()
# exécuter cette boucle lorsque la fenêtre de dialogue est visible
while AnimationDialog.isVisible():
# mettre à jour la vue; important de donner la rétroaction du système d'exploitation la fenêtre de dialogue est vivant
FreeCADGui.updateGui()
# amène la fenêtre de dialogue au premier plan, pour que la fenêtre de dialogue soit toujours visible
QtGui.QWidget.raise_(AnimationDialog)
# valeur de curseur de sortie ici aussi car pendant le calcul, le curseur a peut-être été déplacé
AnimationDialog.CurrentAngle.setText(str(AnimationDialog.slider.value()))
La fenêtre de dialogue définie dans le script ressemble à ceci :
Pour mieux comprendre la syntaxe du script, voici quelques informations de commande :
starWheel.Placement.Rotation.Angle = math.radians(angle)
Ici, nous changeons la propriété de placement Rotation.Angle
de la pièce récupérée précédemment en tant que starWheel
. Cette propriété obtient l'angle comme radian. La fonction radians()
de la bibliothèque math
convertit l'angle du degré en radian.
La propriété Rotation.Angle
utilise l'axe de placement actuel de la pièce (dans notre exemple l'axe X). Pour faire pivoter la pièce, par ex. autour de l'axe Z, on peut définir l'axe de rotation (avant d'appeler la commande de rotation) en utilisant la commande :
starWheel.Placement.Rotation.Axis = FreeCAD.Vector(0,0,1)
Au lieu de tourner, les pièces peuvent également être déplacées. Pour changer par exemple le placement dans la direction Y de la roue, la commande serait :
starWheel.Placement.Base.y = PositionShift
Dans ce cas, nous ne définirions pas la variable angle
mais PositionShift
que nous modifions à chaque boucle.
Il existe différentes manières de définir le placement d'une pièce. Certains sont documentés ici. Malheureusement, il n'y a pas (encore) de liste avec toutes les commandes de placement possibles.
a2p_solver.solveConstraints(document, useTransaction=False/True)
Il s'agit d'une commande spécifique à A2plus. Elle résout les contraintes d'assemblage de l'assemblage que nous avons précédemment obtenu en tant que document
. L'option useTransaction
spécifie si FreeCAD doit stocker chaque modification dans la pile annuler/refaire. Pour les grandes animations, vous pouvez donc la régler sur false
.